import threading
import json
import struct
import socket
import pathlib
from data import database
import os


class Userthread(threading.Thread):
    def __init__(self, userSocket):
        threading.Thread.__init__(self)
        self.dataPath = pathlib.Path(__file__).resolve().parent
        self.userSocket = userSocket
        # 当登入成功保存用户信息
        self.username = None
        self.password = None

    def createBase(self):
        base = database.Base(str(self.dataPath.joinpath('data').joinpath('users.db')))
        try:
            base.createTable(
                'usersInfo', 'username STRING NOT NULL UNIQUE, password STRING NOT NULL')
        except:
            pass
        return base

    # 进行接收信息，并监控用户是否在线
    def recvSafe(self, userSocket, size=1024):
        def afterExit():
            for i in userSockets:
                if userSocket == i:
                    userSockets.remove(userSocket)
            print(userSocket[1], "exiting...")
            print("onlienNum:", len(userSockets))
        try:
            data = userSocket[0].recv(size)
            if not data:
                afterExit()
                return False
            return data
        except ConnectionResetError:
            afterExit()
            return False

    def afterChat(self):
        while True:
            # 接收报头长度
            headerSize = self.recvSafe(self.userSocket, 4)
            if not headerSize: return
            headerSize = struct.unpack('i', headerSize)[0]
            # 接收报头
            headerData = self.recvSafe(self.userSocket, headerSize)
            if not headerData: return
            headerData = json.loads(headerData.decode())
            # 解析数据
            ## 获取数据种类
            dataClass = headerData['dataClass']
            ## 获取数据长度
            dataSize = headerData['dataSize']
            print(dataClass)
            print(dataSize)
            if dataClass == 'loginIn':
                loginData = self.recvSafe(self.userSocket, dataSize)
                if not loginData: return
                loginData = json.loads(loginData.decode())
                print(loginData['username'])
                print(loginData['password'])
                # 判断数据
                ## 创建数据库
                base = self.createBase()
                ## 从usersInfo中获取username=username，判断是否存在然后比对password
                base.cur.execute('select * from usersInfo where username="{}" and password="{}"'.format(loginData['username'], loginData['password']))
                userInfo = base.cur.fetchall()
                print(userInfo)
                if not userInfo:
                    # 没有找到匹配的账户,返回错误
                    self.userSocket[0].send((json.dumps({"code":0})).encode())
                else:
                    # 找到该用户，返回正确，客户端进入聊天界面，加载用户信息
                    # 保存成功登录的用户信息(注销后将被修改)
                    self.username = loginData['username']
                    self.password = loginData['password']
                    self.userSocket[0].send((json.dumps({"code":1})).encode())
                    # 登录成功，进入聊天环节(当duringChat被return即用户掉线，重新进入用户登录注册环节)
                    isOnline = self.duringChat()
                    if not isOnline: return

            elif dataClass == 'register':
                registerData = self.recvSafe(self.userSocket, dataSize)
                if not registerData: return
                registerData = json.loads(registerData.decode())
                print(registerData['username'])
                print(registerData['password'])
                base = self.createBase()
                base.cur.execute('select * from usersInfo where username="{}"'.format(registerData['username']))
                userInfo = base.cur.fetchall()
                if not userInfo:
                    # 找不到用户就保存当前用户
                    base.insertTo('usersInfo', '"{0}", "{1}"'.format(registerData['username'], registerData['password']))
                    self.userSocket[0].send((json.dumps({"code":1})).encode())
                else:
                    self.userSocket[0].send((json.dumps({"code":0})).encode())

    def duringChat(self):
        print(self.username)
        print(self.password)
        # 聊天前缀
        ## 发送用户信息
        ## 发送用户好友信息
        ## 发送系统信息
        ## 发送聊天信息

        # 进行聊天循环
        while True:
            data = self.recvSafe(self.userSocket)
            if not data: return False
        ## 处理私聊信息
        ## 处理群聊信息
        ## 处理大厅信息

    def run(self):
        self.afterChat()

userSockets = []
userThreads = []

# socket setting
rootAddr = ('127.0.0.1', 3000)
rootSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
rootSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

# socket init
rootSocket.bind(rootAddr)
rootSocket.listen(128)
print("running... on", rootAddr)

while True:
    conn, addr = userSocket = rootSocket.accept()
    userSockets.append((conn, addr))

    print(addr, "connecting...")
    print("onlineNum:", len(userSockets))
    userThreads.append(Userthread(userSocket))
    userThreads[-1].start()
